require 'net/http'
require 'md5'
require 'win32ole'

class Kjflickr
def initialize(apikey, secret)
@apikey = apikey
@secret = secret
@boundary = 'thisisboundary' 
@token = ''
@cr = "\r\n"
end
private
def makeparams(params)
  ret = ''
  params.sort.each do |x|
    ret += '&'+ x[0] + '=' + x[1]
  end 
  ret
end
private
def makeapisign(hash)
  MD5.md5(@secret + hash.sort.to_s).to_s
end
private
def apirequest(params)
  url = URI.parse("http://api.flickr.com/services/rest/?#{params}")
  Net::HTTP.get url 
end
private
def getFrob
  param = Hash.new
  param['method'] = 'flickr.auth.getFrob'
  param['api_key'] = @apikey
  param['api_sig'] = makeapisign(param)
  res = apirequest(makeparams(param))
  res[/<frob>\w*-\w*<\/frob>/].sub!('<frob>','').sub!('</frob>','')
end
private
def getToken(frob)
  tokenparam = Hash.new
  tokenparam['method'] = 'flickr.auth.getToken'
  tokenparam['api_key'] = @apikey
  tokenparam['frob'] = frob
  tokenparam['api_sig'] = makeapisign(tokenparam)
  res = apirequest(makeparams(tokenparam))
  res[/<token>\w*-\w*<\/token>/].sub!('<token>','').sub!('</token>', '')
end
public
def authentication(perms)
  # auth code
  loginparam = Hash.new
  loginparam['api_key'] = @apikey
  loginparam['frob'] = getFrob
  loginparam['perms'] = perms
  loginparam['api_sig'] = makeapisign(loginparam)
  strparam = makeparams(loginparam)
  url = URI.parse("http://flickr.com/services/auth/?#{strparam}")

  ie = WIN32OLE.new('InternetExplorer.Application')
  ie.Visible = true 
  ie.Navigate url.to_s
  sleep(1) until ie.ReadyState == 4
  @token = getToken(loginparam['frob'])
  #ie.Quit
end
public
def makeformdata(params)
	ret = ''
  params.sort.each do |x|
  	ret += '--' + @boundary + @cr + "Content-Disposition: form-data; name=\"#{x[0]}\"" + @cr*2 + x[1] + @cr
	end
	ret
end
public
def makephotodata(photopath)
	f = File.open(photopath, 'r')
	photobin = f.read.to_s
	f.close
  ret = '--' + @boundary + @cr + "Content_Disposition: form-data; name=\"photo\" " + "filename=\"image.jpg\"" + @cr
	ret += 'Content-Type: Image/jpeg' + @cr*2 + photobin + @cr + '--' + @boundary + '--'
end
public
def photoupload(photopath)
  url = URI.parse('http://flickr.com/services/upload/')
	req = Net::HTTP::Post.new url.path
	req.content_type= "multipart/form-data; boundary=#{@boundary}";
	req.add_field 'Host', 'api.flickr.com'

	params = Hash.new
	params['api_key'] = @apikey 
	params['auth_token'] = @token 
	params['api_sig'] = makeapisign(params)
	p makeparams(params)
	reqbody = makeformdata(params)
	reqbody += makephotodata(photopath)
	req.set_form_data reqbody
  res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req)} 
	res.body
end
end

#main
apikey='bc847d41420243378c99e5a098ad22a9'
secret='0bb8307fa8fe7dc0'
permsval='write'
flickr = Kjflickr.new(apikey, secret)
flickr.authentication('write')
p flickr.photoupload('c:\\1.gif')

